package com.ysl.netty.server;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.ysl.netty.common.SessionSocket;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;

import java.util.UUID;

public class MyServerHandler extends SimpleChannelInboundHandler<Object> {

    /**
     *	 读取客户端发过来的请求，并且向客户端返回响应的方法
     * @param ctx 上下文，可以获取远程的信息，地址、连接对象
     * @param msg 客户端发来的请求对象
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println(ctx.channel().remoteAddress() + "," + msg);
        if(msg instanceof String)
        {
            JSONObject json=JSONObject.parseObject(msg.toString());
            if(json.containsKey("type"))
            {
                String type = json.getString("type");
                if(type.equals("login"))
                {
                    SessionSocket.likeRedisTemplate.saveChannel(json.getString("userid"),ctx.channel());
                }

                if(type.equals("ping"))
                {

                }
            }
        }

        /*
            write 写入缓冲
            flush 把缓冲的内容清/推出去
            writeAndFlush 写入缓冲，并把缓冲的内容推出去
         */
        ctx.channel().writeAndFlush("服务的from server：" + UUID.randomUUID());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        //可能出现业务判断离线后再次触发 channelInactive
        String userid = SessionSocket.likeRedisTemplate.getUserId(ctx.channel());
        if (StrUtil.isNotEmpty(userid)){
            SessionSocket.likeRedisTemplate.deleteChannel(userid);
            ctx.channel().close();
        }
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
            if (idleStateEvent.state() == IdleState.READER_IDLE) {

            }
        }
        super.userEventTriggered(ctx, evt);
    }

    /**
     * 	出现异常的情况下怎么办
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel ch = ctx.channel();
        //GlobalChannelGroup.channelGroup.add(ch);
        //SocketChannelGroup.likeRedisTemplate.saveChannel(ch.id().asLongText(),ch);

        //System.out.println(SessionSocket.likeRedisTemplate.getOnline());
        super.handlerAdded(ctx);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel ch = ctx.channel();
        String userid = SessionSocket.likeRedisTemplate.getUserId(ctx.channel());
        if(StrUtil.isNotEmpty(userid))
        {
            SessionSocket.likeRedisTemplate.deleteChannel(userid);
        }
        super.handlerRemoved(ctx);
    }
}
